//
//  UIButton+YSEventInterval.m
//  YSKitDemo
//
//  Created by Kyson on 2018/12/13.
//  Copyright © 2018 YangShen. All rights reserved.
//

#import "UIButton+YSEventInterval.h"
#import <objc/runtime.h>

@interface UIButton ()

@property (nonatomic, assign) BOOL ys_eventUnavailable;

@end

@implementation UIButton (YSEventInterval)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        SEL defaultButtonActionSEL = @selector(sendAction:to:forEvent:);
        SEL changeButtonActionSEL = @selector(ys_sendAction:to:forEvent:);
        Method method = class_getInstanceMethod(self, defaultButtonActionSEL);
        Method ys_method = class_getInstanceMethod(self, changeButtonActionSEL);
        
        //添加方法
        BOOL isAdd = class_addMethod(self, defaultButtonActionSEL, method_getImplementation(ys_method), method_getTypeEncoding(ys_method));
        
        if ( isAdd ) {
            //添加成功，那么就替换实现方法
            class_replaceMethod(self, changeButtonActionSEL, method_getImplementation(method), method_getTypeEncoding(method));
        } else {
            //添加不成功，说明已经有方法了，那么直接执行方法实现的对调
            method_exchangeImplementations(method, ys_method);
        }
    });
}

#pragma mark - Action functions
- (void)ys_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
    if (self.ys_eventUnavailable == NO) {
        self.ys_eventUnavailable = YES;
        [self ys_sendAction:action to:target forEvent:event];
        [self performSelector:@selector(setYs_eventUnavailable:) withObject:@(NO) afterDelay:self.ys_eventInterval];
    }
}


#pragma mark - Setter & Getter
- (NSTimeInterval)ys_eventInterval {
    return [objc_getAssociatedObject(self, @selector(ys_eventInterval)) doubleValue];
}

- (void)setYs_eventInterval:(NSTimeInterval)ys_eventInterval {
    objc_setAssociatedObject(self, @selector(ys_eventInterval), @(ys_eventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)ys_eventUnavailable {    
    return [objc_getAssociatedObject(self, @selector(ys_eventUnavailable)) boolValue];
}

- (void)setYs_eventUnavailable:(BOOL)ys_eventUnavailable {
    objc_setAssociatedObject(self, @selector(ys_eventUnavailable), @(ys_eventUnavailable), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end
